﻿using System.Collections;
using DG.Tweening;
using UnityEngine;
using System.Collections.Generic;
using Yoozoo.UI.YGUI;
using System;
using Yoozoo.Mars.Got;

namespace Yoozoo.Gameplay.RTS
{
    /// <summary>
    /// HpAndRage内部自己的状态上下文
    /// 
    /// </summary>
    public struct HpAndRageContext
    {
        /// <summary>
        /// 是否在释放怒气阶段(状态)
        /// </summary>
        public bool m_IsInReleaseRage;

        public float m_curHeroRageMax;
    }
    
    public class HpAndRage : MonoBehaviour
    {
        //保护作用,作为最大怒气传递失败后的保护,暂时写死
        private static int protectedMaxRage = 400;
        public static Vector3 RageEffPos = new Vector3(-45f, -24f, 0);
        
        private const float PercentPerSec = 0.5f;
        private const float TweenColorSpeed = 0.25f;
        private const float TweenColorValue = 0.5f;
        
        [SerializeField] private YImage hpBar;
        [SerializeField] private YImage hpBarBg;
        [SerializeField] private YImage rageBar;

        [SerializeField] private YImage rageBarBG;

        [SerializeField] private YImage whiteHpBar;
        private HpAndRageContext rageContext;

        private Animation animation;

        private float cachedHp;
        
        private Tween whiteHpTween;

        private HudRageEffect rageEff;
        private bool hpInted;
        private int colorState = -1;

        [SerializeField]
        private float finalRageStartTime = 0.4f;//涨怒气开始时间
        [SerializeField]
        private float finalRageCostTime = 2.6f;//涨怒气消耗时间
        private bool hpEnable = false;
        private void Awake()
        {
            hpEnable = hpBar.enabled;
        }
        public void Init()
        {
            SetRageBarProgress(0);
            SetSpriteMatFloat(1, rageBarBG);
            animation = GetComponent<Animation>();
            this.whiteHpBar.enabled = false;
            this.hpInted = false;
            old = 1;
            rageContext.m_IsInReleaseRage = false;
            rageContext.m_curHeroRageMax = -1;
        }

        public void SetRageBarMaxLimit(float maxRage,float curMaxRage)
        {
            if (curMaxRage <= 0) curMaxRage = protectedMaxRage;
            if (curMaxRage != rageContext.m_curHeroRageMax)
            {
                rageContext.m_curHeroRageMax = curMaxRage;
                if (maxRage > 0)
                {
                    SetSpriteMatFloat(curMaxRage/maxRage, rageBarBG);
                }
                else
                {
                    SetSpriteMatFloat(curMaxRage/protectedMaxRage, rageBarBG);
                }
            }
        }

        public void SetRoundRage(int lastRage,int costRage,int finalRage,float maxRage,float curMaxRage)
        {
            if (maxRage == 0)
            {
                return;
            }
            int costAfterRage = lastRage - costRage;
            if (costAfterRage < 0)
            {
                costAfterRage = 0;
            }

            var avAddRage = (finalRage - costAfterRage) / 3f;
            Sequence leftSequeue = DOTween.Sequence();
            if (costRage != 0)
            {
                SetRageBarProgress(Math.Round((double)costAfterRage / maxRage,2),costRage);
            }
            leftSequeue.Insert(finalRageStartTime,
            DOTween.To(() => { return costAfterRage; }, (int rage) =>
            {
                SetRageBarProgress(Math.Round((double)rage / maxRage, 2));
            }, finalRage, finalRageCostTime));

            leftSequeue.Play();
        }

        /// <summary>
        /// 设置怒气槽
        /// </summary>
        /// <param name="progress">0~1</param>
        public void SetRageBarProgress(double progress,int costRage = -1)
        {
            if (!this.rageBar.enabled)
                return;

            if (GetInRageStatus())
                return;

            SetSpriteMatFloat((float)progress, rageBar);

            if (costRage >= 1)
                PlayRageFullEff((int)(costRage/100));
        }

        private void SetSpriteMatFloat(float value,YImage image)
        {
            image.fillAmount = value;
        }
        private float old;
        public void SetHpBarProgress(float progress, bool forceFresh = false)
        {
            SetSpriteMatFloat(progress,hpBar);
            if (!this.hpInted)
            {
                this.hpInted = true;
                SetSpriteMatFloat(progress,whiteHpBar);
            }
            else
            {
                if (progress > old)
                {
                    SetSpriteMatFloat(progress, whiteHpBar);
                }
            }
            //if (progress < 1)
            //{
            //    SetHpActive(true);
            //}
            //else
            //{
            //    SetHpActive(false);
            //}

            int currentColorState = 0;
            if (progress == 1)
            {
                currentColorState = 0;
            }
            else if(progress >= 0.75f && progress < 1)
            {
                currentColorState = 1;
            }
            else if (progress > 0.4f && progress < 0.75f)
            {
                currentColorState = 2;
            }
            else
            {
                currentColorState = 3;
            }

            if (currentColorState != colorState || forceFresh)
            {
                colorState = currentColorState;
                Color color;
                if (colorState == 0 || colorState == 1)
                {
                    ColorUtility.TryParseHtmlString("#ffffff", out color);
                }
                //else if (colorState == 1)
                //{
                //    ColorUtility.TryParseHtmlString("#ffffff", out color);
                //}
                else if(colorState == 2)
                {
                    ColorUtility.TryParseHtmlString("#ffb400", out color);
                }
                else
                {
                    ColorUtility.TryParseHtmlString("#ff2400", out color);
                }
                hpBar.color = new Color(color.r, color.g, color.b,hpBar.color.a);
            }

            if (old - progress <= 0.1f)
                return;

            this.whiteHpBar.enabled = true;
            if (this.whiteHpTween != null)
                this.whiteHpTween.Kill();

            var c = this.whiteHpBar.color;
            c.a = 1;
            this.whiteHpBar.color = c;
            this.whiteHpTween = this.whiteHpBar.DOFade(TweenColorValue, TweenColorSpeed).SetEase(Ease.Linear);
        }

        public void SetHpActive(bool active)
        {
            hpBar.enabled = active;
            hpBarBg.enabled = active;
        }

        public void ShowReleaseSkillEffect()
        {
            animation.Play("ani_sfx_ui_rts_skill_1");
        }

        public void SetRageBarActive(bool active)
        {
            this.rageBar.enabled = active;
            this.rageBarBG.enabled = active;
            if (!active)
            {
                rageContext.m_curHeroRageMax = -1;
            }
        }

        public void SetTeam(int team)
        {
            //this.hpBarMat = InitFillBar(this.hpBar, hpBarMatBlock);
            //var prog = 1.0f;
            //if (this.hpBarMat != null)
            //    prog = this.hpBarMat.GetFloat("_FillAmount");
            //this.hpBarMat.SetFloat("_FillAmount", prog);
            //this.whiteHPBarMat.SetFloat("_FillAmount", prog);
        }

        private void LateUpdate()
        {
            if (!this.whiteHpBar.enabled)
                return;

            var white = whiteHpBar.fillAmount;
            var normal = this.hpBar.fillAmount;
            if (Mathf.Approximately(white, normal))
            {
                this.whiteHpBar.enabled = false;
                return;
            }

            var percent = white - Time.deltaTime * PercentPerSec;
            if (percent < normal)
                percent = normal;

            this.whiteHpBar.fillAmount = percent;
        }

        private void RecycleRageEff(object param)
        {
            ArmyManager.Instance.HudManager.RecoverHudRageEffect(this.rageEff);
            this.rageEff = null;
        }

        private void PlayRageFullEff(int costRage = -1)
        {
            if (this.rageEff != null)
            {
                Timers.inst.Remove(RecycleRageEff);
                this.rageEff.Play(costRage);
                Timers.inst.Add(1.5f, 1, RecycleRageEff);
                return;
            }

            this.rageEff = ArmyManager.Instance.HudManager.GetHudRageEffect();
            this.rageEff.transform.SetParent(transform, true);
            this.rageEff.transform.localPosition = RageEffPos;
            this.rageEff.transform.localScale = Vector3.one;
            this.rageEff.transform.localRotation = Quaternion.identity;
            this.rageEff.SetRage(costRage);
            Timers.inst.Add(1.5f, 1, RecycleRageEff);
        }

        private void Hide()
        {
            if (!this.hpEnable)
                return;
            this.hpEnable = false;
            hpBar.enabled = false;
            hpBarBg.enabled = false;
        }

        private void Show()
        {
            if (this.hpEnable)
                return;

            this.hpEnable = true;
            hpBar.enabled = true;
            hpBarBg.enabled = true;
        }

        internal void SetVisible(bool isShowSoldierCount)
        {
            //if (isShowSoldierCount)
            //{
            //    Show();
            //}
            //else
            //{
            //    Hide();
            //}
        }

        public void Dispose()
        {
            rageContext.m_IsInReleaseRage = false;
            rageContext.m_curHeroRageMax = -1;
        }
        
        #region 状态上下文变更

        public void ChangeRageStatus(bool isInRage)
        {
            if (isInRage != rageContext.m_IsInReleaseRage)
            {
                if (isInRage)
                {
                    SetRageBarProgress(0);
                }
                rageContext.m_IsInReleaseRage = isInRage;
            }
        }

        public bool GetInRageStatus()
        {
            return rageContext.m_IsInReleaseRage;
        }
        #endregion
    }
}
